package org.smile.db.criteria;

import org.smile.lambda.Lambda;
import org.smile.lambda.LambdaUtils;

public abstract class AbstractLambdaCriteria<E> extends AbstractNoLambdaCriteria<E> implements Criteria<E>{

	@Override
	public LambdaCriteria<E> between(Lambda fieldName, Object start, Object end) {
		checkAddAnd();
		criterions.add(Restrictions.between(fieldName, start, end));
		return this;
	}

	@Override
	public Criteria<E> eq(Lambda fieldName, Object value) {
		checkAddAnd();
		criterions.add(Restrictions.eq(fieldName, value));
		return this;
	}

	@Override
	public Criteria<E> ne(Lambda fieldName, Object value) {
		checkAddAnd();
		criterions.add(Restrictions.ne(fieldName, value));
		return this;
	}

	@Override
	public Criteria<E> lt(Lambda fieldName, Object value) {
		checkAddAnd();
		criterions.add(Restrictions.lt(fieldName, value));
		return this;
	}

	@Override
	public Criteria<E> gt(Lambda fieldName, Object value) {
		checkAddAnd();
		criterions.add(Restrictions.gt(fieldName, value));
		return this;
	}

	@Override
	public Criteria<E> le(Lambda fieldName, Object value) {
		checkAddAnd();
		criterions.add(Restrictions.le(fieldName, value));
		return this;
	}

	@Override
	public Criteria<E> ge(Lambda fieldName, Object value) {
		checkAddAnd();
		criterions.add(Restrictions.ge(fieldName, value));
		return this;
	}

	@Override
	public Criteria<E> in(Lambda fieldName, Object value) {
		checkAddAnd();
		criterions.add(Restrictions.in(fieldName, value));
		return this;
	}
	@Override
	public Criteria<E> nin(Lambda fieldName, Object value) {
		checkAddAnd();
		criterions.add(Restrictions.nin(fieldName, value));
		return this;
	}

	@Override
	public Criteria<E> like(Lambda fieldName, String value, MatchMode mathMode) {
		checkAddAnd();
		criterions.add(Restrictions.like(fieldName, value,mathMode));
		return this;
	}

	@Override
	public Criteria<E> like(Lambda fieldName, String value) {
		checkAddAnd();
		criterions.add(Restrictions.like(fieldName, value));
		return this;
	}

	@Override
	public Criteria<E> eqother(Lambda fieldName, Lambda otherField) {
		checkAddAnd();
		criterions.add(Restrictions.eqother(fieldName, otherField));
		return this;
	}

	@Override
	public Criteria<E> neother(Lambda fieldName,Lambda otherField) {
		checkAddAnd();
		criterions.add(Restrictions.neother(fieldName, otherField));
		return this;
	}

	@Override
	public Criteria<E> ltother(Lambda fieldName, Lambda otherField) {
		checkAddAnd();
		criterions.add(Restrictions.ltother(fieldName, otherField));
		return this;
	}

	@Override
	public Criteria<E> gtother(Lambda fieldName, Lambda otherField) {
		checkAddAnd();
		criterions.add(Restrictions.gtother(fieldName, otherField));
		return this;
	}

	@Override
	public Criteria<E> leother(Lambda fieldName, Lambda otherField) {
		checkAddAnd();
		criterions.add(Restrictions.leother(fieldName, otherField));
		return this;
	}

	@Override
	public Criteria<E> geother(Lambda fieldName, Lambda otherField) {
		checkAddAnd();
		criterions.add(Restrictions.geother(fieldName, otherField));
		return this;
	}


	@Override
	public Criteria<E> orderby(Lambda fieldName) {
		orderby.add(new OrderbyCriterion(LambdaUtils.getPropertyName(fieldName)));
		return this;
	}

	@Override
	public Criteria<E> orderby(Lambda fieldName, boolean desc) {
		orderby.add(new OrderbyCriterion(LambdaUtils.getPropertyName(fieldName),desc?"desc":""));
		return this;
	}

	@Override
	public Criteria<E> isnull(Lambda fieldName) {
		checkAddAnd();
		criterions.add(Restrictions.isnull(fieldName));
		return this;
	}

	@Override
	public Criteria<E> notnull(Lambda fieldName) {
		checkAddAnd();
		criterions.add(Restrictions.notnull(fieldName));
		return this;
	}


	@Override
	public Criteria<E> field(Lambda fieldName) {
		queryFields.add(LambdaUtils.getPropertyName(fieldName));
		return this;
	}



	@Override
	public Criteria<E> fields(Lambda first, Lambda... fieldName) {
		queryFields.add(LambdaUtils.getPropertyName(first));
		for(Lambda lambda:fieldName) {
			queryFields.add(LambdaUtils.getPropertyName(lambda));
		}
		return this;
	}

	@Override
	public Criteria<E> nlike(Lambda fieldName, String value) {
		checkAddAnd();
		criterions.add(Restrictions.nlike(fieldName, value));
		return this;
	}

	@Override
	public Criteria<E> nlike(Lambda fieldName, String value, MatchMode mathMode) {
		checkAddAnd();
		criterions.add(Restrictions.nlike(fieldName, value, mathMode));
		return this;
	}



	@Override
	public Criteria<E> set(Lambda<E, ?> fieldName, Object value) {
		 set(LambdaUtils.getPropertyName(fieldName),value);
		 return this;
	}

	@Override
	public Criteria criteria() {
		return this;
	}
}
